package com.javaExtendsDemo.demo1;

/*
 * java中继承的小例子_java_weixin_36888745的博客-CSDN博客
 * https://blog.csdn.net/weixin_36888745/article/details/84072170
 *
 *
 * * 使用继承时的注意事项
 * 如果类之间存在着：is a 的关系，就可以考虑使用继承。
 * 不要为了继承部分功能，而去使用继承。
 * super和this有什么区别?
 * super是一个关键字，代表父类的存储空间标识。(可以理解为父亲的引用)
 *
 * super和this的用法相似。
 *
 * this代表对象的引用(谁调用就代表谁)；
 * super代表当前子类对父类的引用。
 *
 * 使用场景
 *
 * 当子父类出现同名成员时，可以用super进行区分；
 * 子类要调用父类构造函数时，可以使用super语句。
 *
 * 区别
 *
 * 1.成员变量
 *
 * this.变量    --    本类的
 * super.变量    --    父类的
 * 2.构造方法
 *
 * this(...)    --    本类的
 * super(...)    --    父类的
 * 3.成员方法
 *
 * this.方法名()    --    本类的
 * super.方法名()    --    父类的
 *
 * super();和this();都是在构造函数的第一行，不能同时出现。
 *
 * 方法的重写（覆盖）
 * 子类中出现与父类一模一样的方法时（除了权限修饰符，权限修饰符大于等于不包括private，返回值类型，方法名和参数列表相同），会出现覆盖操作，也称为重写或者复写。
 *
 * 父类私有方法，子类看不到，因此父类私有方法的重写也就无从谈起。
 *
 * 覆盖注意事项：
 *
 * 覆盖时，子类方法权限一定要大于等于父类方法权限；
 * 静态只能覆盖静态。
 * 覆盖的使用场景：
 *
 * 当子类需要父类的功能，而功能主体子类有自己特有内容时，可以复写父类中的方法，这样，既沿袭了父类的功能，又定义了子类特有的内容。
 *
 * 方法重写和重载有什么区别？
 *
 * 方法的重写用在子类方法与父类方法一模一样时，除权限修饰符，返回值类型，方法名和参数列表都是相同的。
 * 重载用在同一个类中各方法方法名相同，参数列表不同（与返回值类型没有关系）的情况。
 *
 * 子父类中构造方法的用法：
 *
 * 子类的初始化过程中，首先回去执行父类的初始化动作。因为子类的构造方法中默认有一个super()。子类要使用父类的成员变量，这个初始化，必须在子类初始化之前完成。所以，子类的初始化过程中，会先执行父类的初始化。
 * 如果父类没有无参构造方法
 * 使用super调用父类的带参构造。推荐方式。
 * 使用this调用本身的其他构造。
 * 静态代码块、构造代码块，构造方法的执行顺序：
 *
 * 父类静态代码块→子类静态代码块→父类构造代码块→父类构造方法→子类构造代码块→子类构造方法
 *
 * final关键字
 * final是一个关键字，可以用于修饰类，成员变量，成员方法。
 *
 * 特点：
 *
 * 它修饰的类不能被继承。
 * 它修饰的成员变量是一个常量。
 * 它修饰的成员方法是不能被子类重写的。
 * final修饰的常量定义一般都有书写规范,被final修饰的常量名称,所有字母都大写。
 *
 * final修饰成员变量,必须初始化,初始化有两种
 *
 * 显示初始化；
 * 构造方法初始化。
 * 但是不能两个一起初始化
 * final和private的区别：
 *
 * final修饰的类可以访问；
 * private不可以修饰外部类，但可以修饰内部类（其实把外部类私有化是没有意义的）。
 * final修饰的方法不可以被子类重写；
 * private修饰的方法表面上看是可以被子类重写的，其实不可以，子类是看不到父类的私有方法的。
 * final修饰的变量只能在显示初始化或者构造函数初始化的时候赋值一次，以后不允许更改；
 * private修饰的变量，也不允许直接被子类或一个包中的其它类访问或修改，但是他可以通过set和get方法对其改值和取值。
 *
 */
public class TestAnimal {
    public static void main(String[] args) {
        Dog d = new Dog("二哈", 1, true);//创建一个Dog对象
        d.run();//调用Dog自己的方法
        d.swim();
        d.shout();
        d.eat();//调用Dog继承的Animal的方法
        d.sleep();

        Dog d2 = new Dog();
        d2.setBreed("哮天犬");
        d2.run();//调用Dog自己的方法
        d2.swim();
        d2.shout();
        d2.eat();//调用Dog继承的Animal的方法
        d2.sleep();

        Cat c = new Cat();
        c.setBreed("熊猫");
        c.play();
        c.eat();
        c.sleep();

        Bird b = new Bird();
        b.setBreed("鹦鹉");
        b.fly();
        b.eat();
        b.sleep();
    }
}
